package com.project.frba.bi;

import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.context.ApplicationContext;

import com.project.frba.bi.descriptor.Descriptor;
import com.project.frba.bi.descriptor.DescriptorsLoader;
import com.project.frba.bi.loading.SchemaBuilder;
import com.project.frba.bi.queueing.OlapDAO;

public class ETLExecutor {
	
	private Hashtable<String, ETLThread> descriptorsThreads = new Hashtable<String, ETLThread>();
	private ScheduledThreadPoolExecutor executor;
	
	public ETLExecutor() {
		this.load();
	}
	
	private void load() {
		Collection<Descriptor> descriptors = DescriptorsLoader.getAllDescriptors();
		executor = new ScheduledThreadPoolExecutor(descriptors.size());
		for (Descriptor descriptor : descriptors) {
			ETLThread etlThread = new ETLThread(descriptor);
			descriptorsThreads.put(descriptor.getDescriptorName(), etlThread);
		}
	}
	
	public void removeThread(String descriptorName) {
		ETLThread thread = descriptorsThreads.get(descriptorName);
		executor.remove(thread);
	}
	
	public void addThread(String descriptorName, Long delay){
		ETLThread thread = descriptorsThreads.get(descriptorName);
		executor.schedule(thread, delay, TimeUnit.MINUTES);
	}
	
	public void changeExecutionTime(String descriptorName, Long delay) {
		if(descriptorsThreads.containsKey(descriptorName)){
			removeThread(descriptorName);
		}
		addThread(descriptorName, delay);
	}
	
	public void execute(String descriptorName) {
		ETLThread thread = descriptorsThreads.get(descriptorName);
		new Thread(thread).start();
	}
	
	public void refresh() {
		descriptorsThreads.clear();
		load();
	}
	
	public void executeAll() {
		Long start = getActualSeconds();
		for (String descriptorName : descriptorsThreads.keySet()) {
			execute(descriptorName);
		}
		Long end = getActualSeconds();
		System.out.println("Duration: " + (end-start) );
	}
	
	public void createSchema(String schemaName){
		SchemaBuilder builder = new SchemaBuilder(schemaName);
		ApplicationContext context = BiUtil.getApplicationContext();
		OlapDAO dao = (OlapDAO)context.getBean("olapDao");
		String[] statements = builder.getFullCreationStatement().split(";");
		for (int i = 0; i < statements.length; i++) {
			dao.executeDDLStatement(statements[i] + ";");			
		}
	}
	
	public Long getActualSeconds() {
		GregorianCalendar calendar = new GregorianCalendar();
		return calendar.getTimeInMillis()/1000;
	}
	
	public static void main(String[] args) {
		ETLExecutor executor = new ETLExecutor();
		executor.createSchema("ventasolap");
		executor.executeAll();
		//executor.execute("compArtVend");
	}

}
